package ModelLayer;
import java.util.*;


public class LoanRegister
{
   private ArrayList<Loan>loans;
   private static LoanRegister instance;
    /**
     * Constructor for objects of class LoanRegister
     */
    private LoanRegister()
    {
   loans=new ArrayList<Loan>();
    }

    
    /**
     * Singleton.
     */
    
    public static LoanRegister getInstance(){
          if(instance==null){
            instance=new LoanRegister();
        }
        return instance;
    }
    
    
    /**
     * Add loan.
     */
    
    public void addLoan(Loan loan){
        
        loans.add(loan);
    }
    
    
    /**
     * upgrade loan.
     */
   
     public boolean updateLoanBorrowDate(long id, String borrowdate)
   {
       int index=0;
       boolean found=false;
       while(index<loans.size()&&!found)
       {
           {Loan p = loans.get(index);
           
               if(p.getId()==id)
               {
                   found=true;
                   p.setBorrowDate(borrowdate);
                   System.out.println("Borrow date Updated Succesfully");
                   break;
                }
                else
                {
                    index++;
                }
            }
            
        }
        if (found==false)
        {
            System.out.println("There is no Loan with this ID");
        }
        return found;
    }
    
    
    
    
     public boolean updateLoanPeriod(long id, String period)
   {
       int index=0;
       boolean found=false;
       while(index<loans.size()&&!found)
       {
           {Loan p = loans.get(index);
           
               if(p.getId()==id)
               {
                   found=true;
                   p.setPeriod(period);
                   System.out.println("Period Updated Succesfully");
                   break;
                }
                else
                {
                    index++;
                }
            }
            
        }
        if (found==false)
        {
            System.out.println("There is no Loan with this ID");
        }
        return found;
    }
    
    
     public boolean updateLoanState(long id, String state)
   {
       int index=0;
       boolean found=false;
       while(index<loans.size()&&!found)
       {
           {Loan p = loans.get(index);
           
               if(p.getId()==id)
               {
                   found=true;
                   p.setState(state);
                   System.out.println("State Updated Succesfully");
                   break;
                }
                else
                {
                    index++;
                }
            }
            
        }
        if (found==false)
        {
            System.out.println("There is no Loan with this ID");
        }
        return found;
    }
    
    
    /**
     * Find Loan.
     */
   public Loan findLoan(long id){
         
         boolean found=false;
         int index=0;
         
         while(index<loans.size()&&!found)
         {
             Loan a =loans.get(index);
             if(a.getId()==id){
                 found=true;
                 return loans.get(index);
                }
                else{
                    index++;
                }
            }
            if(found==false){
               System.out.println("There is no loan with that ID");
             
            
         } 
         return null;
        }
        
        public boolean checkIfLoanExists(long id)
        {
            boolean found = false;
            int index=0;
            while(index<loans.size()&&!found)
            {
                Loan l = loans.get(index);
                if(l.getId()==id)
                {
                    found = true;
                    index++;
                    
                }
                else
                {
                    index++;
                }
            }
            return found;
        }
        
        
        /**
         * Create loan.
         */
        public boolean createLoan(long loanId,long dvdId,long personId,String borrowDate, String period)
        {
            boolean success = false;
            Person p = AddressBook.getInstance().findPerson(personId);
            Copy c = DVDRegister.getInstance().findCopy(dvdId);
            DVD d = DVDRegister.getInstance().findDVD(dvdId);
            if(p!=null&c!=null)
            {
                if(d.nrOfCopies()>0)
                {
                    if(checkIfLoanExists(loanId)==false)
                        {
                            Loan l = new Loan(loanId,dvdId,personId,borrowDate,period,"In progress");
                            loans.add(l);
                            p.addLoan(l);
                            c.loanCopy(loanId);
                            d.decreaseNrOfCopies();
                            success = true;
                        }
                        else 
                        {
                            System.out.println("There is already a loan with that ID");
                        }
                }
                
            }
            return success;
        }
        
        public void changeLoanState(long id,String state)
        {
            Loan l = findLoan(id);
            l.setState(state);
        }
            
        
        public void returnCopy(long loanId)
        {
           
            Loan l = findLoan(loanId);
            if(l!=null)
            {
            DVD d = DVDRegister.getInstance().findDVD(l.getDvdId());
            Person p = AddressBook.getInstance().findPerson(l.getPersonId());
            changeLoanState(loanId,"Returned");
            int index=0;
            boolean found = false;
            ArrayList<Copy> copies = d.getListOfCopies();
            
            while(index<copies.size()&&!found)
            {
                Copy c = copies.get(index);
                if(c.getLoanId()==loanId)
                { 
                    found=true;
                    if(c.getLoanedState()==true)
                    {
                        c.setLoanedState(false);
                        System.out.println(checkIfOnTime(l));
                    }
                    else
                    {
                    System.out.println("This copy was already returned");
                    }
                }
                else
                {
                    index++;
                }
            }
            d.increaseNrOfCopies();
            p.removeLoan(l);
        }
        }
        
        public void printLoan(long id)
        {
            Loan l = LoanRegister.getInstance().findLoan(id);
            System.out.println("ID: " + l.getId());
            System.out.println("DVD ID: " + l.getDvdId());
            System.out.println("Person ID: " + l.getPersonId());
            System.out.println("Borrow Date: " + l.getBorrowDate());
            System.out.println("Period: " + l.getPeriod());
            System.out.println("State: " + l.getState());
        }
        
        public boolean removeLoan(long id)
        {
            boolean found = false;
            int index = 0;
            while(index<loans.size()&&!found)
            {
                Loan l = loans.get(index);
                if(l.getId()==id)
                loans.remove(l);
                found=true;
            } 
            if (found==false)
            {
                System.out.println("Loan with id '" + id + " was not found");
            }
            return found;
        }
        
        public void listAllLoans()
        {
            System.out.println("ID   DVD   Person   Borrow Date   Period   State");
            for (Loan l: loans)
            {
                System.out.print(l.getId() + "   " + l.getDvdId() + "    " + l.getPersonId() + "       ");
                System.out.print(l.getBorrowDate() + "    " + l.getPeriod() + "      " + l.getState());
                System.out.print("\n");
            }
        }
        
        private String checkIfOnTime(Loan l)
        {
            String onTime = " ";
            String loanBorrowDate = l.getBorrowDate();
            String[] dayMonthYear;
            dayMonthYear = loanBorrowDate.split("/",3);
            int day = Integer.parseInt(dayMonthYear[0]);
            int month = Integer.parseInt(dayMonthYear[1]);
            int year = Integer.parseInt(dayMonthYear[2]);
            Calendar c = Calendar.getInstance();
            int currentDay = c.get(Calendar.DAY_OF_MONTH);
            int currentMonth = c.get(Calendar.MONTH);
            int currentYear = c.get(Calendar.YEAR);
            c.set(currentYear,currentMonth+1,currentDay);
            Date currentDate = c.getTime();
            c.set(year,month,day);
            int period = Integer.parseInt(l.getPeriod());
            c.add(Calendar.DATE, period);
            Date newBorrowDate = c.getTime();
            if(newBorrowDate.after(currentDate))
            {
                onTime = "This copy was not returned on time.";
            }
            else 
            {
                onTime = "This copy was returned on time.";
            }
            return onTime;
        }
}
        
       
        

